package com.springbootnetty.netty_handler;

import cn.hutool.json.JSONUtil;
import com.springbootnetty.dto.InBody;
import com.springbootnetty.utils.Jt808Util;
import com.springbootnetty.utils.SpringBenUtil;

import com.springbootnetty.netty_server.MyNettyServer;
import com.springbootnetty.server.InServer;
import com.springbootnetty.vo.WebSocketVo;
import com.springbootnetty.web_socket.WebSocketServer;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.PooledByteBufAllocator;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.springframework.stereotype.Component;


import javax.annotation.Resource;
import java.net.InetSocketAddress;


/**
 * MyNettyServerHandler
 */
@Component
public class MyNettyServerHandler extends ChannelInboundHandlerAdapter {

    @Resource
    WebSocketServer webSocketServer;


    /**
     *netty 无法注入server  使用上下文注入
     */
    InServer inServer;

    public MyNettyServerHandler() {
        if (null == inServer)
           this.inServer= SpringBenUtil.getBean(InServer.class);
        System.out.println("MyNettyServerHandler。。。。。执行了构造，注入inServer属性");
    }



    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        String key = getKey(ctx);
        MyNettyServer.clients.add(ctx.channel());
        MyNettyServer.map.put(key, ctx);
        System.out.println("客户端加入链接：channelActive:" + key + "当前设备数量：" + MyNettyServer.map.size());

        //推送加入
        WebSocketVo webSocketVo = new WebSocketVo(1, "1上线");
        String webSocketVoStr = JSONUtil.toJsonStr(webSocketVo);
        webSocketServer.sendInfo(webSocketVoStr, null);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        String key = getKey(ctx);
        MyNettyServer.clients.remove(ctx.channel());
        MyNettyServer.map.remove(key);
        cause.printStackTrace();

        System.out.println("客户端退出链接：exceptionCaught:" + key + "当前设备数量：" + MyNettyServer.map.size());

        String webSocketVoStr = "data";
        webSocketServer.sendInfo(webSocketVoStr, null);
        ctx.close();
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        String key = getKey(ctx);
        MyNettyServer.clients.remove(ctx.channel());
        MyNettyServer.map.remove(key);

        System.out.println("客户端退出链接：channelInactive:" + key + "当前设备数量：" + MyNettyServer.map.size());

        String webSocketVoStr = "data";
        webSocketServer.sendInfo(webSocketVoStr, null);
        ctx.close();
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf inBuf = (ByteBuf) msg;
        InBody inBody = byteToInBody(inBuf);
        byte[] respByte = inServer.handle(inBody );


        String key = getKey(ctx);
        //ai返回全部 25长
        if (25 ==0) {
            String aiList = "data";
            webSocketServer.sendInfo(aiList, null);
        }

        super.channelRead(ctx, msg);

        ByteBuf byteBuf = PooledByteBufAllocator.DEFAULT.directBuffer();
        byteBuf.writeBytes(respByte);
        ctx.channel().writeAndFlush(byteBuf);
//        MyNettyServer.clients.writeAndFlush(byteBuf); // 将Server端接收到的信息广播到client端
    }

    /**
     * 向所有设备发送数据
     */
    public static void sendDataAll(byte[] data) {
        ByteBuf byteBuf = PooledByteBufAllocator.DEFAULT.directBuffer();//声明一个bytebuf 对象
        byteBuf.writeBytes(data);//获取字节数组
        MyNettyServer.clients.writeAndFlush(byteBuf);//全部通道发送
        byteBuf.clear();
    }

    /**
     * 获取客户端ip
     */
    public String getKey(ChannelHandlerContext ctx) {
        String id = ctx.channel().id().asShortText();
        InetSocketAddress client = (InetSocketAddress) ctx.channel().remoteAddress();
        String clientIP = client.getAddress().getHostAddress();
        return clientIP + ":" + id;
    }


    /**
     * 将数据封装，结构
     */
    public InBody byteToInBody(ByteBuf inBuf){
        String oldStr = ByteBufUtil.hexDump(inBuf).toUpperCase();
        byte[] oldBytes = ByteBufUtil.getBytes(inBuf);
        byte[] newBytes=Jt808Util.unescape(oldBytes);//反转义
        String newStr = Jt808Util.byte6ToString(newBytes);
        return new InBody(oldStr,newStr,oldBytes,newBytes);
    }

}

